package com.sms.sendservice.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sms.common.exception.SmsException;
import com.sms.common.result.Result;
import com.sms.common.result.ResultCode;
import com.sms.sendservice.entity.SmsChannel;
import com.sms.sendservice.entity.SmsSendTask;
import com.sms.sendservice.mapper.SmsChannelMapper;
import com.sms.sendservice.mapper.SmsSendTaskMapper;
import com.sms.sendservice.service.SmsSendService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class SmsSendServiceImpl extends ServiceImpl<SmsSendTaskMapper, SmsSendTask> implements SmsSendService {
    
    @Autowired
    private SmsSendTaskMapper smsSendTaskMapper;
    
    @Autowired
    private SmsChannelMapper smsChannelMapper;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Override
    @Transactional
    public Result<String> sendSms(String phoneNumber, String content, Long templateId, Long userId) {
        if (StrUtil.isBlank(phoneNumber) || StrUtil.isBlank(content)) {
            return Result.error(ResultCode.PARAM_ERROR, "手机号和内容不能为空");
        }
        
        // 智能路由选择最优通道
        String channelCode = selectBestChannel(phoneNumber, content);
        
        // 创建发送任务
        SmsSendTask task = createSendTask(phoneNumber, content, templateId, userId, channelCode);
        
        // 立即发送
        return executeSendTask(task);
    }
    
    @Override
    @Transactional
    public Result<String> sendSmsAtTime(String phoneNumber, String content, Long templateId, Long userId, LocalDateTime sendTime) {
        if (StrUtil.isBlank(phoneNumber) || StrUtil.isBlank(content)) {
            return Result.error(ResultCode.PARAM_ERROR, "手机号和内容不能为空");
        }
        
        if (sendTime == null || sendTime.isBefore(LocalDateTime.now())) {
            return Result.error(ResultCode.PARAM_ERROR, "发送时间不能为空且不能早于当前时间");
        }
        
        // 智能路由选择最优通道
        String channelCode = selectBestChannel(phoneNumber, content);
        
        // 创建定时发送任务
        SmsSendTask task = createSendTask(phoneNumber, content, templateId, userId, channelCode);
        task.setPlanSendTime(sendTime);
        task.setStatus(0); // 待发送
        
        smsSendTaskMapper.insert(task);
        
        // 这里可以集成Quartz等定时任务框架
        log.info("创建定时发送任务，任务ID: {}, 计划发送时间: {}", task.getTaskId(), sendTime);
        
        return Result.success("定时发送任务创建成功，任务ID: " + task.getTaskId());
    }
    
    @Override
    @Transactional
    public Result<String> batchSendSms(List<String> phoneNumbers, String content, Long templateId, Long userId) {
        if (phoneNumbers == null || phoneNumbers.isEmpty()) {
            return Result.error(ResultCode.PARAM_ERROR, "手机号列表不能为空");
        }
        
        if (StrUtil.isBlank(content)) {
            return Result.error(ResultCode.PARAM_ERROR, "短信内容不能为空");
        }
        
        int successCount = 0;
        int failCount = 0;
        
        for (String phoneNumber : phoneNumbers) {
            try {
                Result<String> result = sendSms(phoneNumber, content, templateId, userId);
                if (result.getCode() == 200) {
                    successCount++;
                } else {
                    failCount++;
                }
            } catch (Exception e) {
                log.error("批量发送短信失败，手机号: {}", phoneNumber, e);
                failCount++;
            }
        }
        
        return Result.success(String.format("批量发送完成，成功: %d, 失败: %d", successCount, failCount));
    }
    
    @Override
    public String selectBestChannel(String phoneNumber, String content) {
        // 查询所有可用的通道
        QueryWrapper<SmsChannel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1) // 启用状态
                   .orderByDesc("weight") // 按权重排序
                   .orderByAsc("priority"); // 按优先级排序
        
        List<SmsChannel> channels = smsChannelMapper.selectList(queryWrapper);
        
        if (channels.isEmpty()) {
            throw new SmsException(ResultCode.SMS_CHANNEL_UNAVAILABLE, "没有可用的短信通道");
        }
        
        // 简单的通道选择策略：选择权重最高的通道
        // 实际项目中可以实现更复杂的路由算法
        SmsChannel bestChannel = channels.get(0);
        
        log.info("选择通道: {}, 权重: {}", bestChannel.getChannelName(), bestChannel.getWeight());
        
        return bestChannel.getChannelCode();
    }
    
    @Override
    public String switchChannel(String phoneNumber, String failedChannelCode) {
        // 查询除失败通道外的其他可用通道
        QueryWrapper<SmsChannel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1) // 启用状态
                   .ne("channel_code", failedChannelCode) // 排除失败的通道
                   .orderByDesc("weight")
                   .orderByAsc("priority");
        
        List<SmsChannel> channels = smsChannelMapper.selectList(queryWrapper);
        
        if (channels.isEmpty()) {
            throw new SmsException(ResultCode.SMS_CHANNEL_UNAVAILABLE, "没有可用的备用通道");
        }
        
        SmsChannel backupChannel = channels.get(0);
        
        log.info("通道切换: {} -> {}", failedChannelCode, backupChannel.getChannelCode());
        
        return backupChannel.getChannelCode();
    }
    
    @Override
    @Transactional
    public Result<String> retrySendSms(String taskId) {
        if (StrUtil.isBlank(taskId)) {
            return Result.error(ResultCode.PARAM_ERROR, "任务ID不能为空");
        }
        
        QueryWrapper<SmsSendTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("task_id", taskId);
        
        SmsSendTask task = smsSendTaskMapper.selectOne(queryWrapper);
        if (task == null) {
            return Result.error(ResultCode.PARAM_ERROR, "发送任务不存在");
        }
        
        if (task.getRetryCount() >= task.getMaxRetryCount()) {
            return Result.error(ResultCode.PARAM_ERROR, "已达到最大重试次数");
        }
        
        // 增加重试次数
        task.setRetryCount(task.getRetryCount() + 1);
        task.setStatus(1); // 发送中
        task.setSendTime(LocalDateTime.now());
        
        smsSendTaskMapper.updateById(task);
        
        // 执行重试发送
        return executeSendTask(task);
    }
    
    @Override
    public Result<Object> getSendStatus(String taskId) {
        if (StrUtil.isBlank(taskId)) {
            return Result.error(ResultCode.PARAM_ERROR, "任务ID不能为空");
        }
        
        QueryWrapper<SmsSendTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("task_id", taskId);
        
        SmsSendTask task = smsSendTaskMapper.selectOne(queryWrapper);
        if (task == null) {
            return Result.error(ResultCode.PARAM_ERROR, "发送任务不存在");
        }
        
        return Result.success(task);
    }
    
    @Override
    @Transactional
    public Result<String> cancelSendTask(String taskId) {
        if (StrUtil.isBlank(taskId)) {
            return Result.error(ResultCode.PARAM_ERROR, "任务ID不能为空");
        }
        
        QueryWrapper<SmsSendTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("task_id", taskId);
        
        SmsSendTask task = smsSendTaskMapper.selectOne(queryWrapper);
        if (task == null) {
            return Result.error(ResultCode.PARAM_ERROR, "发送任务不存在");
        }
        
        // 只能取消待发送的任务
        if (task.getStatus() != 0) {
            return Result.error(ResultCode.PARAM_ERROR, "只能取消待发送的任务");
        }
        
        task.setStatus(4); // 已取消
        smsSendTaskMapper.updateById(task);
        
        return Result.success("任务取消成功");
    }
    
    /**
     * 创建发送任务
     */
    private SmsSendTask createSendTask(String phoneNumber, String content, Long templateId, Long userId, String channelCode) {
        SmsSendTask task = new SmsSendTask();
        task.setTaskId(IdUtil.fastSimpleUUID());
        task.setPhoneNumber(phoneNumber);
        task.setContent(content);
        task.setTemplateId(templateId);
        task.setUserId(userId);
        task.setChannelCode(channelCode);
        task.setStatus(1); // 发送中
        task.setSendTime(LocalDateTime.now());
        task.setRetryCount(0);
        task.setMaxRetryCount(3);
        
        return task;
    }
    
    /**
     * 执行发送任务
     */
    private Result<String> executeSendTask(SmsSendTask task) {
        try {
            // 模拟短信发送
            log.info("开始发送短信，任务ID: {}, 手机号: {}, 内容: {}", 
                    task.getTaskId(), task.getPhoneNumber(), task.getContent());
            
            // 这里应该调用实际的短信通道API
            // 模拟发送延迟
            Thread.sleep(100);
            
            // 模拟发送成功
            task.setStatus(2); // 发送成功
            task.setResult("SUCCESS");
            
            smsSendTaskMapper.insert(task);
            
            log.info("短信发送成功，任务ID: {}", task.getTaskId());
            return Result.success("短信发送成功，任务ID: " + task.getTaskId());
            
        } catch (Exception e) {
            log.error("短信发送失败，任务ID: {}", task.getTaskId(), e);
            
            task.setStatus(3); // 发送失败
            task.setErrorMessage(e.getMessage());
            
            smsSendTaskMapper.insert(task);
            
            return Result.error(ResultCode.SMS_SEND_FAILED, "短信发送失败: " + e.getMessage());
        }
    }
} 